package com.hyt.it.ogt.pj.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.hyt.common.apiInfor.ApiResponse;
import com.hyt.core.base.BaseServiceImpl;
import com.hyt.core.util.DateUtils;
import com.hyt.core.util.UUIDUtils;
import com.hyt.it.ogt.pj.common.Constants;
import com.hyt.it.ogt.pj.common.MarkException;
import com.hyt.it.ogt.pj.common.ResponseCode;
import com.hyt.it.ogt.pj.enums.CommonEnums;
import com.hyt.it.ogt.pj.enums.MarkStatusTransFinishEnum;
import com.hyt.it.ogt.pj.enums.SubjectScoreStageEnums;
import com.hyt.it.ogt.pj.feign.KwClient;
import com.hyt.it.ogt.pj.mapper.*;
import com.hyt.it.ogt.pj.model.dto.NeedReduceDTO;
import com.hyt.it.ogt.pj.model.dto.StudentExtendDTO;
import com.hyt.it.ogt.pj.model.dto.pj.PjConfigCode;
import com.hyt.it.ogt.pj.model.entity.*;
import com.hyt.it.ogt.pj.model.param.TaskPageParam;
import com.hyt.it.ogt.pj.model.vo.*;
import com.hyt.it.ogt.pj.service.*;
import com.hyt.model.PageParam;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 考生表 服务实现类
 * </p>
 *
 * @author qiaozj
 * @since 2020-07-09
 */
@Service
@Slf4j
public class StudentServiceImpl extends BaseServiceImpl<StudentMapper, Student> implements IStudentService {

    protected Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private KwClient kwClient;

    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private IPaperService paperService;

    @Autowired
    private IItemScoreService itemScoreService;

    @Autowired
    private ItemScoreMapper itemScoreMapper;

    @Autowired
    private IStudentConfigService studentConfigService;

    @Autowired
    private TaskMapper taskMapper;

    @Autowired
    private IPieceScoreService pieceScoreService;

    @Autowired
    private PieceScoreMapper pieceScoreMapper;

    @Autowired
    private ProjectMapper projectMapper;

    @Autowired
    private ExamExpertMapper examExpertMapper;

    @Autowired
    private SubjectMapper subjectMapper;

    @Autowired
    private SubjectScoreMapper subjectScoreMapper;

    @Autowired
    private PaperItemMapper paperItemMapper;

    @Autowired
    private IPieceScoreLogService pieceScoreLogService;

    @Autowired
    private PaperMapper paperMapper;

    @Autowired
    private ProjectSettingMapper projectSettingMapper;

    @Autowired
    private ITaskService taskService;


    /**
     * 初始化考生
     *
     * @param projectId 评卷项目id
     * @return 返回添加到数据库中的考生列表
     */
    @Override
    public List<StudentExtendDTO> initStudent(String projectId) {
        // 获取试卷信息
        List<Paper> papers = paperService.selectBySubject(projectId, null);
        // 用是否传准考证号来区分是否为增量添加评卷任务
        List<StudentExtendDTO> allStudentDTOs = new LinkedList<>();
        int current = 1;
        int pageSize = 500;
        boolean hasNext = true;
        while (hasNext) {
            ApiResponse<PageParam<StudentExtendDTO>> res = kwClient.getProjectStudentPage(projectId, current, pageSize);
            logger.info("## 拉取到的评卷学生数据-current:{},pageSize:{}, data:{}", current, pageSize, JSONObject.toJSONString(res));
            if (null != res && null != res.getData() && CollectionUtils.isNotEmpty(res.getData().getRecords())) {
                List<StudentExtendDTO> studentDTOs = res.getData().getRecords();
                allStudentDTOs.addAll(studentDTOs);
                current++;
            } else {
                hasNext = false;
            }
        }
        if (CollectionUtils.isNotEmpty(allStudentDTOs)) {
            //过滤掉无主观题的考生
            for (Iterator<StudentExtendDTO> iterator = allStudentDTOs.iterator(); iterator.hasNext(); ) {
                StudentExtendDTO studentExtendDTO = iterator.next();
                if (null != studentExtendDTO.getHasSubjective() && !studentExtendDTO.getHasSubjective()) {
                    iterator.remove();
                }
            }
        }
        List<Student> insertStudents = new LinkedList<>();
        if (CollectionUtils.isNotEmpty(allStudentDTOs)) {
            for (StudentExtendDTO studentDTO : allStudentDTOs) {
                // 处理考生个人信息数据
                saveStudentConfig(studentDTO);
                // 保存基础表
                Student student = new Student();
                BeanUtils.copyProperties(studentDTO, student);
                student.setId(null);
                // 密号和准考证设置一样
                student.setEncodeId(studentDTO.getAdmissionNum());
                for (Paper paper : papers) {
                    String paperId = paper.getId();
                    String sjpaperId = paper.getPaperId();
                    Integer paperVersion = paper.getPaperVersion();
                    if (paper.getPackageId() == null) {
                        // 试卷包为空设置的是试卷id
                        if (sjpaperId.equals(student.getPaperId()) && paperVersion.equals(student.getPaperVersion())) {
                            logger.info("## 设置的试卷id为:{}", paper.getId());
                            student.setPaperId(paperId);
                            student.setPaperVersion(paperVersion);
                            break;
                        }
                    } else {
                        // 试卷包不为空设置试卷包的id
                        if (paper.getPackageId().equals(studentDTO.getPackageId()) && sjpaperId.equals(student.getPaperId()) && paperVersion == student.getPaperVersion()) {
                            logger.info("## 设置的试卷包id为:{}", paper.getPackageId());
                            student.setPaperId(paperId);
                            student.setPaperVersion(paperVersion);
                            student.setPackageId(paper.getPackageId());
                            student.setPackageVersion(paper.getPackageVersion());
                            break;
                        }
                    }
                }
                insertStudents.add(student);
            }
        }
        if (CollectionUtils.isNotEmpty(insertStudents)) {
            this.saveBatch(insertStudents);
        }
        return allStudentDTOs;
    }

    /**
     * 保存考生基本信息
     */
    private void saveStudentConfig(StudentExtendDTO studentDTO) {
        logger.info("## 保存考生个人信息数据:{}", JSONObject.toJSONString(studentDTO));
        List<PjConfigCode> configs = studentDTO.getConfigs();
        if (CollectionUtils.isEmpty(configs)) {
            return;
        }
        List<StudentConfig> pjConfigCodeList = new ArrayList<>();
        for (PjConfigCode pjConfigCode : configs) {
            studentDTO.setCandidateId(pjConfigCode.getCandidateId());
            StudentConfig studentConfig = new StudentConfig();
            studentConfig.setAdmissionNum(studentDTO.getAdmissionNum());
            studentConfig.setCandidateId(pjConfigCode.getCandidateId());
            studentConfig.setConfigCode(pjConfigCode.getConfigCode());
            studentConfig.setConfigId(pjConfigCode.getCjConfigID());
            studentConfig.setConfigValue(pjConfigCode.getConfigValue());
            studentConfig.setProjectId(studentDTO.getProjectId());
            // 保存一些主要的配置信息
            if ("性别".equals(pjConfigCode.getConfigCode())) {
                studentDTO.setSex(pjConfigCode.getConfigValue());
            }
            if ("证件号码".equals(pjConfigCode.getConfigCode())) {
                studentDTO.setIdNo(pjConfigCode.getConfigValue());
            }
            if ("手机号".equals(pjConfigCode.getConfigCode())) {
                studentDTO.setTelephone(pjConfigCode.getConfigValue());
            }
            if ("证件照".equals(pjConfigCode.getConfigCode()) || "个人照片".equals(pjConfigCode.getConfigCode())) {
                String configValue = pjConfigCode.getConfigValue();
                if (!StringUtils.isEmpty(configValue)) {
                    studentDTO.setAvatar(configValue.split(",")[0]);
                }
            }
            pjConfigCodeList.add(studentConfig);

        }
        studentConfigService.saveBatch(pjConfigCodeList);
    }


    /**
     * 单个添加增量考生
     *
     * @param projectId 评卷项目id
     * @param admission 准考证号
     */
    @Override
    public List<StudentExtendDTO> incrementStudent(String projectId, String admission) {
        // 用是否传准考证号来区分是否为增量添加评卷任务
        ApiResponse<List<StudentExtendDTO>> res = kwClient.getProjectStudent(projectId, admission);
        logger.info("## 拉取到的新增评卷学生数据:{}", JSONObject.toJSONString(res));

        List<StudentExtendDTO> studentDTOs = res.getData();
        List<Paper> papers = paperService.selectBySubject(projectId, null);
        logger.debug("## 打印试卷:{}", JSONObject.toJSONString(papers));


        List<Student> insertStudents = new ArrayList<>();
        for (StudentExtendDTO studentDTO : studentDTOs) {
            if (null != studentDTO.getHasSubjective() && !studentDTO.getHasSubjective()) {
                continue;
            }
            // 处理考生个人信息数据
            saveStudentConfig(studentDTO);

            // 保存基础表
            Student student = new Student();
            BeanUtils.copyProperties(studentDTO, student);
            student.setId(null);
            for (Paper paper : papers) {
                String paperId = paper.getId();
                String sjpaperId = paper.getPaperId();
                Integer paperVersion = paper.getPaperVersion();
                if (paper.getPackageId() == null) {
                    if (sjpaperId.equals(student.getPaperId()) && paperVersion == student.getPaperVersion()) {
                        logger.info("## 设置的试卷id为:{}", paper.getId());
                        student.setPaperId(paperId);
                        student.setPackageVersion(paperVersion);
                        student.setPackageId(null);
                        student.setPackageVersion(null);
                        break;
                    }
                } else {
                    //试卷包
                    if (paper.getPackageId().equals(studentDTO.getPackageId()) && sjpaperId.equals(student.getPaperId()) && paperVersion == student.getPaperVersion()) {
                        logger.info("## 设置的试卷包id为:{}", paper.getPackageId());
                        student.setPaperId(paperId);
                        student.setPaperVersion(paperVersion);
                        student.setPackageId(paper.getPackageId());
                        student.setPackageVersion(paper.getPackageVersion());
                        break;
                    }
                }
            }
            insertStudents.add(student);
        }
        this.saveBatch(insertStudents);
        return studentDTOs;
    }

    @Override
    public Integer incrementStudent(String projectId, String admission, List<Paper> papers) {
        return null;
    }


    @Override
    public Student getByAdmissionNum(String projectId, String subjectId, String admissionNum) {
        return studentMapper.getByAdmissionNum(projectId, subjectId, admissionNum);
    }

    @Override
    public IPage<Student> selectStudent(PageParam<Student> pageParam, String projectId, String status, String studentName) {
        IPage<Student> page = null;
        // 报名账单
        page = studentMapper.selectStudent(pageParam, projectId, status, studentName);
        List<Student> list = page.getRecords();
        page.setRecords(list);
        return page;
    }


    /**
     * 根据评卷项目id查询考生
     *
     * @param projectId 评卷项目id
     * @return 返回评卷项目考生
     */
    @Override
    public List<Student> selectByProject(String projectId) {
        List<Student> students = studentMapper.selectByProject(projectId);
        return students;
    }

    /**
     * 获取某项目或者某项目下某科目考生数量
     *
     * @param projectId 评卷项目id
     * @param subjectId 评卷科目id
     * @return 返回考生数量
     */
    @Override
    public Integer getStudentNum(String projectId, String subjectId) {
        return studentMapper.getStudentNum(projectId, subjectId);
    }

    /**
     * 根据科目id查询考生
     *
     * @param subjectId 科目id
     * @return 返回科目考生
     */
    @Override
    public List<Student> selectBySubject(String subjectId) {
        List<Student> students = studentMapper.selectBySubject(subjectId);
        return students;
    }


    @Override
    public Page<TaskPageItemVo> taskStudentPage(Page<TaskPageItemVo> pageParam, TaskPageParam taskPageParam) {
        //获取排序分数顺序
        List<BigDecimal> scores = studentMapper.taskStudentScore(taskPageParam);
        Map<BigDecimal, Long> scoreMap = null;
        if (CollectionUtils.isNotEmpty(scores)) {
            List<BigDecimal> uniqueList = scores.stream().distinct().collect(Collectors.toList());
            scoreMap = new HashMap<>(scores.size());
            long count = 1;
            for (BigDecimal score : uniqueList) {
                scoreMap.put(score, count);
                count++;
            }

        }
        // 分页查询所有的task列表
        Page<TaskPageItemVo> page = studentMapper.taskStudentPage(pageParam, taskPageParam);
        if (null == page || CollectionUtils.isEmpty(page.getRecords())) {
            return page;
        }
        // 获取项目信息
        Project project = projectMapper.selectById(taskPageParam.getProjectId());
        if (null == project) {
            return page;
        }
        // 获取所有的科目信息
        QueryWrapper<Subject> subjectWrapper = new QueryWrapper<>();
        subjectWrapper.lambda().eq(Subject::getProjectId, taskPageParam.getProjectId());
        List<Subject> subjects = subjectMapper.selectList(subjectWrapper);
        Map<String, String> subjectMap = subjects.stream().collect(Collectors.toMap(Subject::getSubjectId, Subject::getSubjectName, (key1, key2) -> key2));

        // 获取评卷专家
        QueryWrapper<ExamExpert> examExpertWrapper = new QueryWrapper<>();
        examExpertWrapper.lambda().eq(ExamExpert::getProjectId, taskPageParam.getProjectId());
        List<ExamExpert> examExperts = examExpertMapper.selectList(examExpertWrapper);
        Map<String, ExamExpert> expertMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(examExperts)) {
            expertMap = examExperts.stream().collect(Collectors.toMap(ExamExpert::getExpertId, ExamExpert -> ExamExpert, (key1, key2) -> key2));
        }

        //查询评卷开始时间评卷结束时间
//        Map<String,Date> markStartTimeMap = new HashMap<>();
//        Map<String,Date> markEndTimeMap = new HashMap<>();
        Map<String, Date> beginDateMap = new HashMap<>();
        Map<String, Date> endDateMap = new HashMap<>();
        Map<String, List<String>> expertNameMap = new HashMap<>();
        Set<String> encodeIds = page.getRecords().stream().map(e -> e.getAdmissionNo()).collect(Collectors.toSet());
        Set<String> pieceIds = page.getRecords().stream().map(e -> e.getPieceId()).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(encodeIds) || CollectionUtils.isEmpty(pieceIds)) {
            return page;
        }
        // 查出所有的评卷块记录
        QueryWrapper<PieceScore> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(PieceScore::getDelFlag, false).in(PieceScore::getPieceId, pieceIds).in(PieceScore::getEncodeId, encodeIds);
        List<PieceScore> pieceScores = pieceScoreMapper.selectList(wrapper);
        // 获取所有的考生的评分记录
//        QueryWrapper<ItemScore> itemScoreWrapper = new  QueryWrapper<ItemScore>();
//        itemScoreWrapper.lambda().eq(ItemScore :: getDelFlag,false).in(ItemScore ::getPieceId , pieceIds).in(ItemScore :: getEncodeId , encodeIds);
//        List<ItemScore> itemScores = itemScoreMapper.selectList(itemScoreWrapper);
//        Map<String,List<ItemScore>> itemScoreMap = itemScores .stream().collect(Collectors.groupingBy(c -> c.getEncodeId()));
        // 按照考生维度分组
        Map<String, List<PieceScore>> pieceScoreMap = pieceScores.stream().collect(Collectors.groupingBy(c -> c.getEncodeId()));
        for (Map.Entry<String, List<PieceScore>> entry : pieceScoreMap.entrySet()) {
            List<PieceScore> tempPieceScores = entry.getValue();
            if (CollectionUtils.isEmpty(tempPieceScores)) {
                continue;
            }
            List<String> expertNames = new ArrayList<>(tempPieceScores.size());
            for (PieceScore pieceScore : tempPieceScores) {
                if (MapUtils.isEmpty(expertMap) || null == expertMap.get(pieceScore.getUserId())) {
                    continue;
                }
                expertNames.add(expertMap.get(pieceScore.getUserId()).getExpertName());
            }
            expertNameMap.put(entry.getKey(), expertNames);
            // 虚拟考场，现考现评开始计算评卷开始时间、结束时间
            if (CommonEnums.EXAM_CLASSFICATION_2.getCode().equals(project.getExamClassfication())
                    || CommonEnums.EXAM_CLASSFICATION_1.getCode().equals(project.getExamClassfication())) {
                List<PieceScore> beginPieceScores = tempPieceScores.stream().filter(e -> null != e.getMarkStartTime()).collect(Collectors.toList());
                beginPieceScores.sort(Comparator.comparing(PieceScore::getMarkStartTime));
                if (!CollectionUtils.isEmpty(beginPieceScores)) {
                    beginDateMap.put(entry.getKey(), beginPieceScores.get(0).getMarkStartTime());
                }
                // 评卷专家全部评完才算结束
                List<PieceScore> endPieceScores = tempPieceScores.stream().filter(e -> null != e.getMarkEndTime() && CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(e.getFinish())).collect(Collectors.toList());
                if (endPieceScores != null && endPieceScores.size() == tempPieceScores.size()) {
                    endPieceScores.sort(Comparator.comparing(PieceScore::getMarkEndTime));
                    if (!CollectionUtils.isEmpty(endPieceScores)) {
                        endDateMap.put(entry.getKey(), endPieceScores.get(tempPieceScores.size() - 1).getMarkEndTime());
                    }
                }
            }
        }
        QueryWrapper<Student> studentWrapper = new QueryWrapper<>();
        studentWrapper.lambda().eq(Student::getProjectId, taskPageParam.getProjectId()).in(Student::getAdmissionNum, encodeIds);
        List<Student> students = studentMapper.selectList(studentWrapper);
        Map<String, String> studentMap = students.stream().collect(Collectors.toMap(Student::getAdmissionNum, Student::getStudentName, (key1, key2) -> key2));
        for (TaskPageItemVo taskPageItemVo : page.getRecords()) {

            if (MapUtils.isNotEmpty(subjectMap)) {
                taskPageItemVo.setSubjectName(subjectMap.get(taskPageItemVo.getSubjectId()));
            }
            if (MapUtils.isNotEmpty(expertNameMap)) {
                taskPageItemVo.setExpertName(expertNameMap.get(taskPageItemVo.getAdmissionNo()));
            }
            if (MapUtils.isNotEmpty(studentMap) && null != studentMap.get(taskPageItemVo.getAdmissionNo())) {
                taskPageItemVo.setStudentName(studentMap.get(taskPageItemVo.getAdmissionNo()));
            }
            if (CommonEnums.EXAM_CLASSFICATION_2.getCode().equals(project.getExamClassfication())) {
                if (MapUtils.isNotEmpty(beginDateMap)) {
                    taskPageItemVo.setMarkStartTime(beginDateMap.get(taskPageItemVo.getAdmissionNo()));
                }
                if (MapUtils.isNotEmpty(endDateMap)) {
                    taskPageItemVo.setMarkEndTime(endDateMap.get(taskPageItemVo.getAdmissionNo()));
                }
                if (null != taskPageItemVo.getMarkStartTime() && null != taskPageItemVo.getMarkEndTime()) {
                    taskPageItemVo.setAnswerTime((taskPageItemVo.getMarkEndTime().getTime() - taskPageItemVo.getMarkStartTime().getTime()) / 1000);
                }
            }
            //排名
            if (MapUtils.isNotEmpty(scoreMap) && null != taskPageItemVo.getScore()
                    && null != scoreMap.get(taskPageItemVo.getScore())) {
                taskPageItemVo.setRank(scoreMap.get(taskPageItemVo.getScore()));
            }
            //未完成不显示主观题得分、试题总分
            if (!CommonEnums.MARK_STATUS_2.getCode().equals(taskPageItemVo.getMarkStatus())) {
                taskPageItemVo.setSubjectiveScore(null);
                taskPageItemVo.setScore(null);
            }
            //评卷状态
            MarkStatusTransFinishEnum markStatusTransFinishEnum = MarkStatusTransFinishEnum.getByFinish(taskPageItemVo.getMarkStatus());
            taskPageItemVo.setFinish(null == markStatusTransFinishEnum ? null : markStatusTransFinishEnum.getFinish());

        }
        return page;
    }


    @Override
    public IPage<StudentVo> getStudentList(PageParam<StudentVo> pageParam, String projectId, String subjectId, String paperItem, String placeId, String roomId, String batchId, String name, String currUserId) {
        //先获取学生的列表
        IPage<StudentVo> studentVoIPage = null;

        //先获取学生的列表
        studentVoIPage = studentMapper.getStudentListByTaskInfo(pageParam, projectId, subjectId, placeId, batchId, roomId, name, currUserId);
        // 获取paperItem信息
        PaperItem paperItemInfo = paperItemMapper.selectById(paperItem);
        if (null == paperItemInfo) {
            return new PageParam<>();
        }
        //获取所有的taskid
        List<String> taskIds = new ArrayList<>();
        List<String> admissionNums = new ArrayList<>();
        for (StudentVo record : studentVoIPage.getRecords()) {
            admissionNums.add(record.getAdmissionNum());
        }
        // 根据项目id和考生准考证号码获取task列表
        Map<String, Task> taskMap = new HashMap<>();
        List<Task> allTask = taskMapper.getStudentSubjectTaskByAdmissionNums(projectId, subjectId, admissionNums);
        if (!CollectionUtils.isEmpty(allTask)) {
            for (Task task : allTask) {
                taskMap.put(task.getEncodeId(), task);
                taskIds.add(task.getId());
            }
        }

        // 根据当前登录人，和所有的taskid获取评分列表
        Map<String, ItemScoreVo> iteMap = new HashMap<>();
        List<ItemScoreVo> itemScoreVos = itemScoreMapper.getStudentItemScoreByItemId(paperItemInfo.getId(), taskIds, currUserId);
        if (!CollectionUtils.isEmpty(itemScoreVos)) {
            for (ItemScoreVo itemScoreVo : itemScoreVos) {
                iteMap.put(itemScoreVo.getEncodeId(), itemScoreVo);
            }
        }
        QueryWrapper<ProjectSetting> studentWrapper = new QueryWrapper<>();
        studentWrapper.lambda().eq(ProjectSetting::getProjectId, projectId);
        List<ProjectSetting> projectSettings = projectSettingMapper.selectList(studentWrapper);
        //设置已评未评(题目维度)
        for (StudentVo record : studentVoIPage.getRecords()) {
            record.setRejudge(CollectionUtils.isEmpty(projectSettings) ? null : projectSettings.get(0).getRejudge());
            String admissionNum = record.getEncodeId();
            Task task = taskMap.get(admissionNum);
            if (null != task) {
                record.setTaskId(task.getId());

            }
            record.setItemId(paperItemInfo.getId());
            //题目为空得分为空，可能存在全部提交但是未给小题打分打分
            if (MapUtils.isEmpty(iteMap)) {
                if (null != record.getPieceScoreFinish() && CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(record.getPieceScoreFinish())) {
                    record.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
                } else {
                    record.setFinish(CommonEnums.PIECCE_SCORE_FINSH_0.getCode());
                }

            } else {
                //全部小题都打分的考生
                if (!StringUtils.isEmpty(record.getEncodeId())) {
                    if (iteMap.containsKey(record.getEncodeId())) {
                        ItemScoreVo itemScoreVo = iteMap.get(record.getEncodeId());
                        if (null != itemScoreVo.getFinish() &&
                                CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(itemScoreVo.getFinish())) {
                            record.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
                        } else {
                            record.setFinish(CommonEnums.PIECCE_SCORE_FINSH_0.getCode());
                        }
                        record.setItemScore(itemScoreVo.getItemScore());
                        record.setItemScoreId(itemScoreVo.getItemScoreId());
                        record.setRemark(itemScoreVo.getRemark());
                    } else {
                        if (null != record.getPieceScoreFinish() && CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(record.getPieceScoreFinish())) {
                            record.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
                        } else {
                            record.setFinish(CommonEnums.PIECCE_SCORE_FINSH_0.getCode());
                        }
                    }
                }

            }
        }

        //排序，将状态为未完成的排列在list第一位
        if (!CollectionUtils.isEmpty(studentVoIPage.getRecords())) {
            studentVoIPage.getRecords().sort(Comparator.comparing(StudentVo::getFinish));
        }

        //设置评卷开始时间
        /*不能在这里设置，这里是分页数据，改到了，提交单个评卷
        if(!CollectionUtils.isEmpty(taskIds)){
            QueryWrapper<PieceScore> wrapper = new  QueryWrapper<>();
            wrapper.lambda().eq(PieceScore :: getDelFlag,false).in(PieceScore ::getTaskId , taskIds);
            List<PieceScore> pieceScores = pieceScoreMapper.selectList(wrapper);
            if(!CollectionUtils.isEmpty(pieceScores)){
                for (PieceScore pieceScore: pieceScores){
                    if(null == pieceScore.getMarkStartTime()){
                        pieceScore.setMarkStartTime(DateUtils.asDate(LocalDateTime.now()));
                    }
                }
            }
            pieceScoreService.updateBatchById(pieceScores);
        }*/
        return studentVoIPage;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setStudentAbsent(String taskId, String admissionNum, String userId) {
        //更新为缺席
        Task task = taskMapper.selectById(taskId);
        if (null == task) {
            return false;
        }
        task.setId(taskId);
        task.setMarkStatus(CommonEnums.TASK_MARK_STATUS_2.getCode());
        task.setAbsent(CommonEnums.STUDENT_ABSENT_1.getCode());
        taskMapper.updateById(task);
        //更新piecescore表中标志为已评
        List<PieceScore> pisList = pieceScoreMapper.getPieceScoreByTaskId(task.getId(), null);
        // 已经评卷的题目
        List<ItemScoreVo> itemScoreVos = itemScoreService.getStudentItemScore(task.getProjectId(), task.getAdmissionNum(), null);
        Map<String, List<ItemScoreVo>> itemScoreMap = null;
        if (!CollectionUtils.isEmpty(itemScoreVos)) {
            itemScoreMap = itemScoreVos.stream().collect(Collectors.groupingBy(c -> c.getUserId()));
            List<String> itemScoreIds = itemScoreVos.stream().map(e -> e.getId()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(itemScoreIds)) {
                itemScoreMapper.updateItemScoreByUserId(itemScoreIds, null);
            }
        }
        // 需要补齐itemscore表中的数据
        List<PaperItemVo> paperItemVos = getAllPaperItemByProjectIdAndSubjectId(task.getProjectId(), task.getSubjectId());

        if (!org.springframework.util.CollectionUtils.isEmpty(itemScoreVos)) {
            for (Iterator<PaperItemVo> iterator = paperItemVos.iterator(); iterator.hasNext(); ) {
                PaperItemVo paperItemVo = iterator.next();
                for (ItemScoreVo itemScoreVo : itemScoreVos) {
                    if (paperItemVo.getId().equals(itemScoreVo.getItemId())) {
                        iterator.remove();
                    }
                }
            }
        }
        for (PieceScore pieceScore : pisList) {
            if (!org.springframework.util.CollectionUtils.isEmpty(paperItemVos)) {
                for (PaperItemVo paperItemVo : paperItemVos) {
                    // 一：保存评分数据
                    ItemScore itemScore = new ItemScore();
                    itemScore.setScore(new BigDecimal("0"));
                    itemScore.setPieceId(task.getPieceId());
                    itemScore.setItemId(paperItemVo.getId());
                    itemScore.setTaskId(task.getId());
                    itemScore.setUserId(pieceScore.getUserId());
                    itemScore.setItemViewPoint(true);
                    itemScore.setEncodeId(pieceScore.getEncodeId());
                    itemScore.setCreateBy(userId);
                    itemScore.setUpdateBy(userId);
                    itemScore.setCreateDate(LocalDateTime.now());
                    itemScore.setUpdateDate(LocalDateTime.now());
                    itemScore.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
                    itemScore.setStage(Constants.MARK_STAGE);
                    itemScore.setRemark("缺席");
                    // 如果是保存，那么追加成绩
                    itemScoreService.save(itemScore);
                }
            }
        }

        // 科目主观题分数
        BigDecimal subjectSubjectiveScore = new BigDecimal("0");
        if (!CollectionUtils.isEmpty(pisList)) {
            for (PieceScore pieceScore : pisList) {
                BigDecimal allItemSubjectiveScore = new BigDecimal("0");
                if (MapUtils.isNotEmpty(itemScoreMap) && null != itemScoreMap.get(pieceScore.getUserId())) {
                    for (ItemScoreVo itemScoreVo : itemScoreMap.get(pieceScore.getUserId())) {
                        allItemSubjectiveScore = allItemSubjectiveScore.add(null == itemScoreVo.getScore() ? BigDecimal.ZERO : itemScoreVo.getScore());
                    }
                }
                BigDecimal score = new BigDecimal("0");
                if (null != pieceScore.getObjectiveScore()) {
                    score = score.add(pieceScore.getObjectiveScore()).add(allItemSubjectiveScore);
                } else {
                    score = score.add(allItemSubjectiveScore);
                }
                pieceScore.setScore(score);
                pieceScore.setSubjectiveScore(allItemSubjectiveScore);
                pieceScore.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
                pieceScore.setUpdateBy(userId);
                pieceScore.setUpdateDate(LocalDateTime.now());
                pieceScore.setMarkEndTime(DateUtils.asDate(LocalDateTime.now()));
                if (null == pieceScore.getMarkStartTime()) {
                    pieceScore.setMarkStartTime(DateUtils.asDate(LocalDateTime.now()));
                }
                if (pieceScore.getSubjectiveScore() != null) {
                    subjectSubjectiveScore = subjectSubjectiveScore.add(pieceScore.getSubjectiveScore());
                }

            }
            pieceScoreService.updateBatchById(pisList);

        }
        // 处理subjectscore数据
        SubjectScore subjectScore = subjectScoreMapper.getStudentSubjectScore(task.getProjectId(), task.getSubjectId(), task.getAdmissionNum());
        // 如果已经完成，则触发总分计算
        BigDecimal pingjunScore = subjectSubjectiveScore.divide(new BigDecimal(pisList.size()), 2, BigDecimal.ROUND_HALF_UP);
        if (null != pingjunScore) {
            subjectScore.setSubjectiveScore(pingjunScore);
        }
        if (null != pingjunScore && null == subjectScore.getObjectiveScore()) {
            subjectScore.setTotalScore(pingjunScore);
        }
        if (null != pingjunScore && null != subjectScore.getObjectiveScore()) {
            subjectScore.setTotalScore(pingjunScore.add(subjectScore.getObjectiveScore()));
        }
        subjectScore.setCollectStatus(Integer.valueOf(SubjectScoreStageEnums.SUMMARY.getCode()));
        // 更新科目汇总分数
        subjectScoreMapper.updateById(subjectScore);
        // 调用考务设置为缺席
        log.info("项目id：" + task.getProjectId() + "考生准考证：" + task.getAdmissionNum() + "状态码：" + CommonEnums.KW_STUDENT_ABSENT_40.getCode());
        kwClient.updateCandidateAbsent(task.getProjectId(), task.getAdmissionNum(), CommonEnums.KW_STUDENT_ABSENT_40.getCode());

        return true;
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean setStudentNotAbsent(String taskId, String admissionNum, String userId) {
        //更新为缺席
        Task task = taskMapper.selectById(taskId);
        if (null == task) {
            return false;
        }
        task.setId(taskId);
        task.setMarkStatus(CommonEnums.TASK_MARK_STATUS_1.getCode());
        task.setAbsent(CommonEnums.STUDENT_ABSENT_0.getCode());
        taskMapper.updateById(task);

        //更新piecescore表中标志为未评
        List<PieceScore> pisList = pieceScoreMapper.getPieceScoreByTaskId(task.getId(), null);
        if (!CollectionUtils.isEmpty(pisList)) {
            for (PieceScore pieceScore : pisList) {
                // 获取当前科目的所有评卷items
//        		BigDecimal allItemSubjectiveScore =  new BigDecimal("0");
//                List<ItemScoreVo>  itemScoreVos = itemScoreService.getStudentItemScore(task.getProjectId(), admissionNum, userId);
//                if(!CollectionUtils.isEmpty(itemScoreVos)) {
//                	for (ItemScoreVo itemScoreVo : itemScoreVos) {
//                		allItemSubjectiveScore = allItemSubjectiveScore.add(itemScoreVo.getScore());
//					}
//                }
//                BigDecimal score =  new BigDecimal("0");
//            	if(null != pieceScore.getObjectiveScore()) {
//            		score = score.add(pieceScore.getObjectiveScore()).add(allItemSubjectiveScore);
//            	}else {
//            		score = score.add(allItemSubjectiveScore);
//            	}
//            	pieceScore.setScore(score);
//            	pieceScore.setSubjectiveScore(allItemSubjectiveScore);
                pieceScore.setFinish(CommonEnums.PIECCE_SCORE_FINSH_2.getCode());
                pieceScore.setUpdateBy(userId);
                pieceScore.setUpdateDate(LocalDateTime.now());
                pieceScore.setMarkEndTime(null);
            }
            pieceScoreService.updateBatchById(pisList);
        }
        //更新ItemScore为评卷中
        List<ItemScoreVo> itemScoreVos = itemScoreService.getStudentItemScore(task.getProjectId(), admissionNum, null);
        if (!CollectionUtils.isEmpty(itemScoreVos)) {
            List<String> itemScoreIds = itemScoreVos.stream().map(e -> e.getId()).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(itemScoreIds)) {
                itemScoreMapper.updateItemScoreFinish(itemScoreIds, null);
            }
        }
        // 调用考务设置为缺席
        kwClient.updateCandidateAbsent(task.getProjectId(), task.getAdmissionNum(), CommonEnums.KW_STUDENT_ABSENT_0.getCode());

        return true;
    }

    @Override
    @Transactional
    public boolean studentAnswerSingleEvaluate(ItemScoreSaveVo itemScoreSaveVo, String currUserId) {
        log.info("保存的小题是:{}", JSON.toJSON(itemScoreSaveVo));
        //获取task
        Task task = null;
        if (!StringUtils.isEmpty(itemScoreSaveVo.getTaskId())) {
            task = taskMapper.selectById(itemScoreSaveVo.getTaskId());
        }
        if (null == task) {
            return false;
        }
        //保存题目信息
        if (!StringUtils.isEmpty(itemScoreSaveVo.getItemScoreId())) {
            //修改，
            ItemScore itemScore = itemScoreService.getById(itemScoreSaveVo.getItemScoreId());
            if (null == itemScore) {
                return true;
            }
            if (!StringUtils.isEmpty(itemScoreSaveVo.getPieceId())) {
                itemScore.setPieceId(itemScoreSaveVo.getPieceId());
            } else {
                itemScore.setPieceId(task.getPieceId());
            }
            itemScore.setScore(itemScoreSaveVo.getItemScore());
            itemScore.setUpdateBy(currUserId);
            itemScore.setUpdateDate(LocalDateTime.now());
            itemScore.setRemark(itemScoreSaveVo.getRemark());
            itemScore.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
            itemScoreService.updateById(itemScore);
        } else {
            //新增
            ItemScore itemScore = new ItemScore();
            itemScore.setId(itemScoreSaveVo.getItemScoreId());
            itemScore.setScore(itemScoreSaveVo.getItemScore());
            if (!StringUtils.isEmpty(itemScoreSaveVo.getPieceId())) {
                itemScore.setPieceId(itemScoreSaveVo.getPieceId());
            } else {
                itemScore.setPieceId(task.getPieceId());
            }
            itemScore.setItemId(itemScoreSaveVo.getItemId());
            itemScore.setTaskId(itemScoreSaveVo.getTaskId());
            itemScore.setUserId(itemScoreSaveVo.getUserId());
            itemScore.setItemViewPoint(true);
            itemScore.setEncodeId(itemScoreSaveVo.getAdmissionNum());
            itemScore.setCreateBy(itemScoreSaveVo.getUserId());
            itemScore.setUpdateBy(itemScoreSaveVo.getUserId());
            itemScore.setCreateDate(LocalDateTime.now());
            itemScore.setUpdateDate(LocalDateTime.now());
            itemScore.setStage(Constants.MARK_STAGE);
            itemScore.setRemark(itemScoreSaveVo.getRemark());
            itemScore.setFinish(CommonEnums.PIECCE_SCORE_FINSH_1.getCode());
            itemScoreService.save(itemScore);
        }


        //获取所有题目
        List<PaperItemVo> paperItemVos = getAllPaperItemByProjectIdAndSubjectId(task.getProjectId(), task.getSubjectId());

        // 获取当前科目的所有评卷items
        List<ItemScoreVo> itemScoreVos = itemScoreService.getStudentItemScore(task.getProjectId(), itemScoreSaveVo.getAdmissionNum(), currUserId);
        // 是否已经完成所有题目的评分
        Boolean finishAllItems = Boolean.TRUE;
        //计算主观题得分
        BigDecimal allItemSubjectiveScore = new BigDecimal("0");

        //判断是否是最后一道题
        if (!CollectionUtils.isEmpty(itemScoreVos)) {
            Map<String, Integer> finishAllItemMap = new HashMap<>();
            for (ItemScoreVo itemScoreVo : itemScoreVos) {
                finishAllItemMap.put(itemScoreVo.getItemId(), itemScoreVo.getFinish());
            }
            for (PaperItemVo paperItemVo : paperItemVos) {
                if (MapUtils.isEmpty(finishAllItemMap) || !CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(finishAllItemMap.get(paperItemVo.getId()))) {
                    finishAllItems = Boolean.FALSE;
                }
            }
            //计算主观题得分
            for (ItemScoreVo itemScoreVo : itemScoreVos) {
                if (!itemScoreVo.getItemId().equals(itemScoreSaveVo.getItemId())) {
                    allItemSubjectiveScore = allItemSubjectiveScore.add(itemScoreVo.getScore());
                }
            }
            allItemSubjectiveScore = allItemSubjectiveScore.add(itemScoreSaveVo.getItemScore());
        }

        // 更新PieceScore数据
        PieceScore pieceScoreSelect = pieceScoreMapper.getByPieceIdAndTaskIdAndEncodeId(task.getSubjectId(), task.getPieceId(), task.getId(), itemScoreSaveVo.getAdmissionNum(), itemScoreSaveVo.getUserId());

        // 评第一道题，设置评卷开始时间
        if (null == pieceScoreSelect.getMarkStartTime()) {
            pieceScoreSelect.setMarkStartTime(DateUtils.asDate(LocalDateTime.now()));
            pieceScoreService.updateById(pieceScoreSelect);
        }

        // 如果主观题为空
        if (null != pieceScoreSelect) {
            if (finishAllItems) {
                BigDecimal score = new BigDecimal("0");
                if (null != pieceScoreSelect.getObjectiveScore()) {
                    score = score.add(pieceScoreSelect.getObjectiveScore()).add(allItemSubjectiveScore);
                } else {
                    score = score.add(allItemSubjectiveScore);
                }

                pieceScoreSelect.setScore(score);
                pieceScoreSelect.setSubjectiveScore(allItemSubjectiveScore);
                pieceScoreSelect.setUpdateDate(LocalDateTime.now());
               /* 这里不是结束时间和评卷次数，在全部提交的时候更新
                pieceScoreSelect.setMarkEndTime(new Date());
                pieceScoreSelect.setLastMarkTime(new Date());
                Integer marktimes = pieceScoreSelect.getMarkTimes();
                if(null == marktimes) {
                    marktimes = Integer.valueOf(0);
                }else {
                    marktimes = marktimes + 1;
                }
                pieceScoreSelect.setMarkTimes(marktimes);
                long l = pieceScoreSelect.getMarkEndTime().getTime() - pieceScoreSelect.getMarkStartTime().getTime();
                pieceScoreSelect.setDuration(new BigDecimal(l / 1000));*/
                pieceScoreMapper.updateById(pieceScoreSelect);
                pieceScoreLogService.save(buildPieceScoreLog(pieceScoreSelect));
            } else {
                pieceScoreSelect.setFinish(CommonEnums.PIECCE_SCORE_FINSH_2.getCode());
                BigDecimal score = new BigDecimal("0");
                if (null != pieceScoreSelect.getObjectiveScore()) {
                    score = score.add(pieceScoreSelect.getObjectiveScore()).add(allItemSubjectiveScore);
                } else {
                    score = score.add(allItemSubjectiveScore);
                }
                if (null == pieceScoreSelect.getMarkStartTime()) {
                    pieceScoreSelect.setMarkStartTime(new Date());
                }
                pieceScoreSelect.setScore(score);
                pieceScoreSelect.setSubjectiveScore(allItemSubjectiveScore);
                pieceScoreSelect.setUpdateDate(LocalDateTime.now());
                pieceScoreSelect.setLastMarkTime(new Date());
                pieceScoreMapper.updateById(pieceScoreSelect);
                // 同时更新task状态为评卷中
                task.setMarkStatus(CommonEnums.TASK_MARK_STATUS_1.getCode());
                taskMapper.updateById(task);
            }
        }


        // 科目主观题分数
        BigDecimal subjectSubjectiveScore = BigDecimal.ZERO;
        // 计算是不是已经评完
        boolean flag = true;
        //更新subjectScore，（存在交叉评卷，所以需要查询所有的专家都评卷完才更新subjectScore）
        List<PieceScore> picList = pieceScoreMapper.getPieceScoreByTaskId(itemScoreSaveVo.getTaskId(), null);
        for (PieceScore pieceScore : picList) {
            if (pieceScoreSelect.getId().equals(pieceScore.getId())) {
                pieceScore.setSubjectiveScore(pieceScoreSelect.getSubjectiveScore());
            }
            if (pieceScore.getSubjectiveScore() != null) {
                subjectSubjectiveScore = subjectSubjectiveScore.add(pieceScore.getSubjectiveScore());
            }
            if (!CommonEnums.PIECCE_SCORE_FINSH_1.getCode().equals(pieceScore.getFinish())) {
                flag = false;
            }
        }
        if (flag) {
            // 处理subjectscore数据
            SubjectScore subjectScore = subjectScoreMapper.getStudentSubjectScore(task.getProjectId(), task.getSubjectId(), task.getAdmissionNum());
            // 如果已经完成，则触发总分计算
            BigDecimal averageScore = subjectSubjectiveScore.divide(new BigDecimal(picList.size()), 2, BigDecimal.ROUND_HALF_UP);
            if (null != averageScore) {
                subjectScore.setSubjectiveScore(averageScore);
            }
            // 返回小题得分
            List<CandidateSubjectiveScoreVO> candidateSubjectiveScoreVOS = taskService.getCandidateSubjectiveScoreVOs(task.getProjectId(), task.getAdmissionNum());
            // 这里需要特别处理下，如果计算的四舍五入的总分数和小题分数不一致，则取小题的总分数，和其他系统保持一致
            BigDecimal allChildSubjectiveScore = BigDecimal.ZERO;
            if (CollectionUtils.isNotEmpty(candidateSubjectiveScoreVOS)) {
                for (Iterator<CandidateSubjectiveScoreVO> iterator = candidateSubjectiveScoreVOS.iterator(); iterator.hasNext(); ) {
                    CandidateSubjectiveScoreVO candidateSubjectiveScoreVO = iterator.next();
                    allChildSubjectiveScore = allChildSubjectiveScore.add(candidateSubjectiveScoreVO.getScore());
                }
            }
            if (null != allChildSubjectiveScore) {
                subjectScore.setChildSubjectiveScore(allChildSubjectiveScore);
            }

            if (null != averageScore && null == subjectScore.getObjectiveScore()) {
                subjectScore.setTotalScore(averageScore);
            }
            if (null != averageScore && null != subjectScore.getObjectiveScore()) {
                subjectScore.setTotalScore(averageScore.add(subjectScore.getObjectiveScore()));
            }
            subjectScore.setCollectStatus(Integer.valueOf(SubjectScoreStageEnums.SUMMARY.getCode()));
            // 更新科目汇总分数
            subjectScoreMapper.updateById(subjectScore);

            // 同时更新task状态为已结束
            task.setMarkStatus(CommonEnums.TASK_MARK_STATUS_2.getCode());
            taskMapper.updateById(task);
        }

        return true;
    }

    private List<PaperItemVo> getAllPaperItemByProjectIdAndSubjectId(String projectId, String subjectId) {
        // 找考生所有的需要作答题目
        String paperId = paperMapper.getPaperIdByProjectIdAndSubject(projectId, subjectId);
        List<PaperItemVo> paperItemVos = paperItemMapper.selectPaperItemVoList(paperId);
        for (Iterator<PaperItemVo> iterator = paperItemVos.iterator(); iterator.hasNext(); ) {
            PaperItemVo paperItemVo = iterator.next();
            paperItemVo.setProjectId(projectId);
            paperItemVo.setSubjectId(subjectId);
            // 所有的题目里面排除大题，排除复合题, 大题，和单选题
            if ("compound".equals(paperItemVo.getItemType())
                    || "topic".equals(paperItemVo.getItemType())
                    || "single".equals(paperItemVo.getItemType())) {
                iterator.remove();
            }
        }
        return paperItemVos;
    }

    private PieceScoreLog buildPieceScoreLog(PieceScore pieceScore) {
        PieceScoreLog pieceScoreLog = new PieceScoreLog();
        pieceScoreLog.setId(UUIDUtils.newSortUUID());
        pieceScoreLog.setObjectiveScore(pieceScore.getObjectiveScore());
        pieceScoreLog.setPieceScoreId(pieceScore.getId());
        pieceScoreLog.setScore(pieceScore.getScore());
        pieceScoreLog.setSubjectiveScore(pieceScore.getSubjectiveScore());
        pieceScoreLog.setUserId(pieceScore.getUserId());
        return pieceScoreLog;
    }


    @Override
    public Student getLastOneStudentByProject(String projectId) {
        Student student = studentMapper.getLastOneStudentByProject(projectId);
        return student;
    }

    @Override
    public List<Student> getAllStudentByProjectAndSubjectId(String projectId, String subjectId) {
        log.info("## getAllStudentByProjectAndSubjectId params:{},{}", projectId, subjectId);
        List<Student> allStudents = new ArrayList<Student>();
        boolean flag = true;
        Integer pageSize = 200;
        Integer pageNum = 1;
        while (flag) {
            try {
                PageInfo<Student> pageInfo = PageHelper.startPage(pageNum, pageSize).doSelectPageInfo(() -> {
                    studentMapper.selectByProjectAndSubjectId(projectId, subjectId);
                });
                if (CollectionUtils.isNotEmpty(pageInfo.getList())) {
                    allStudents.addAll(pageInfo.getList());
                    pageNum++;
                } else {
                    flag = false;
                }
            } catch (Exception e) {
                log.error("## selectByProjectAndSubjectId error", e);
                flag = false;
            }
        }
        return allStudents;
    }

    @Override
    public void saveStudent(String projectId, List<StudentExtendDTO> studentDTOs) {
        List<Student> insertStudents = new ArrayList<>();
        for (StudentExtendDTO studentDTO : studentDTOs) {
            if (null != studentDTO.getHasSubjective() && !studentDTO.getHasSubjective()) {
                continue;
            }
            // 处理考生个人信息数据
            saveStudentConfig(projectId, studentDTO);

            List<Paper> papers = paperService.selectParersBySubjectId(projectId, null);
            // 保存基础表
            Student student = new Student();
            BeanUtils.copyProperties(studentDTO, student);
            student.setId(null);
            for (Paper paper : papers) {
                String paperId = paper.getId();
                String sjpaperId = paper.getPaperId();
                Integer paperVersion = paper.getPaperVersion();
                if (paper.getPackageId() == null) {
                    if (sjpaperId.equals(student.getPaperId()) && paperVersion == student.getPaperVersion()) {
                        log.info("## 设置的试卷id为:{}", paper.getId());
                        student.setPaperId(paperId);
                        student.setPaperVersion(paperVersion);
                        student.setPackageId(null);
                        student.setPackageVersion(null);
                        break;
                    }
                } else {
                    // 试卷包
                    if (paper.getPackageId().equals(studentDTO.getPackageId()) && sjpaperId.equals(student.getPaperId()) && paperVersion == student.getPaperVersion()) {
                        log.info("## 设置的试卷包id为:{}", paper.getPackageId());
                        student.setPaperId(paperId);
                        student.setPaperVersion(paperVersion);
                        student.setPackageId(paper.getPackageId());
                        student.setPackageVersion(paper.getPackageVersion());
                        break;
                    }
                }
            }
            insertStudents.add(student);
        }
        if (org.springframework.util.CollectionUtils.isEmpty(insertStudents)) {
            throw new MarkException(ResponseCode.INIT_PROJECT_NO_STUDENT.toString());
        } else {
            saveBatch(insertStudents);
        }
    }

    @Override
    public void saveStudentConfig(String projectId, StudentExtendDTO studentDTO) {
        List<PjConfigCode> configs = studentDTO.getConfigs();
        if (org.springframework.util.CollectionUtils.isEmpty(configs)) {
            return;
        }
        List<StudentConfig> pjConfigCodeList = new ArrayList<>();
        for (PjConfigCode pjConfigCode : configs) {
            studentDTO.setCandidateId(pjConfigCode.getCandidateId());
            StudentConfig studentConfig = new StudentConfig();
            studentConfig.setAdmissionNum(studentDTO.getAdmissionNum());
            studentConfig.setCandidateId(pjConfigCode.getCandidateId());
            studentConfig.setConfigCode(pjConfigCode.getConfigCode());
            studentConfig.setConfigId(pjConfigCode.getCjConfigID());
            studentConfig.setConfigValue(pjConfigCode.getConfigValue());
            studentConfig.setProjectId(studentDTO.getProjectId());
            // 保存一些主要的配置信息
            if ("性别".equals(pjConfigCode.getConfigCode())) {
                studentDTO.setSex(pjConfigCode.getConfigValue());
            }
            if ("证件号码".equals(pjConfigCode.getConfigCode())) {
                studentDTO.setIdNo(pjConfigCode.getConfigValue());
            }
            if ("手机号".equals(pjConfigCode.getConfigCode())) {
                studentDTO.setTelephone(pjConfigCode.getConfigValue());
            }
            if ("证件照".equals(pjConfigCode.getConfigCode()) || "个人照片".equals(pjConfigCode.getConfigCode())) {
                String configValue = pjConfigCode.getConfigValue();
                if (!StringUtils.isEmpty(configValue)) {
                    studentDTO.setAvatar(configValue.split(",")[0]);
                }
            }
            pjConfigCodeList.add(studentConfig);

        }
        studentConfigService.saveBatch(pjConfigCodeList);

    }

    @Override
    public void reduceExamNum(String projectId, String admissionNum) {
        List<NeedReduceDTO> needReduceList = studentMapper.getNeedReduce(projectId, Lists.newArrayList(admissionNum));
        //更新科目实考人数
        for (NeedReduceDTO needReduce : needReduceList) {
            if (subjectMapper.updateExamNum(projectId, needReduce.getSubjectId(), needReduce.getExamNum()) != 1) {
                throw new MarkException(ResponseCode.UPDATE_STUDENTNUM_ERROR.toString());
            }
        }
    }
}
